// #include <qt.hpp>

#include "qt.hpp"
// #include "dialog.h"
// #include <Qt/qapplication.h>
// #include <QtGui/qpushbutton.h>
// #include "dlgmy.h"
// #include "dlg9x9.h"
#include "tsc_dlg.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#ifdef __cplusplus
extern "C" {
#endif

extern struct pt  screen_pt[5];
extern struct pt  adc_pt[5];



tsc_dlg *g_dlgmsg;


typedef struct {
	int x[5], xfb[5];
	int y[5], yfb[5];
	int a[7];
} calibration;


int perform_calibration(calibration *cal)
{
	int j;
	float n, x, y, x2, y2, xy, z, zx, zy;
	float det, a, b, c, e, f, i;
	float scaling = 65536.0;

	// Get sums for matrix
	n = x = y = x2 = y2 = xy = 0;
	for(j = 0; j < 5; j++) {
		n += 1.0;
		x += (float)cal->x[j];
		y += (float)cal->y[j];
		x2 += (float)(cal->x[j] * cal->x[j]);
		y2 += (float)(cal->y[j] * cal->y[j]);
		xy += (float)(cal->x[j] * cal->y[j]);
	}

	// Get determinant of matrix -- check if determinant is too small
	det = n * (x2 * y2 - xy * xy) + x * (xy * y - x * y2) + y * (x * xy - y * x2);
	if(det < 0.1 && det > -0.1) {
		printf("ts_calibrate: determinant is too small -- %f\n", det);
		return 0;
	}

	// Get elements of inverse matrix
	a = (x2 * y2 - xy * xy) / det;
	b = (xy * y - x * y2) / det;
	c = (x * xy - y * x2) / det;
	e = (n * y2 - y * y) / det;
	f = (x * y - n * xy) / det;
	i = (n * x2 - x * x) / det;

	// Get sums for x calibration
	z = zx = zy = 0;
	for(j = 0; j < 5; j++) {
		z += (float)cal->xfb[j];
		zx += (float)(cal->xfb[j] * cal->x[j]);
		zy += (float)(cal->xfb[j] * cal->y[j]);
	}

	// Now multiply out to get the calibration for framebuffer x coord
	cal->a[0] = (int)((a * z + b * zx + c * zy) * (scaling));
	cal->a[1] = (int)((b * z + e * zx + f * zy) * (scaling));
	cal->a[2] = (int)((c * z + f * zx + i * zy) * (scaling));

	printf("%f %f %f\n", (a * z + b * zx + c * zy),
	       (b * z + e * zx + f * zy),
	       (c * z + f * zx + i * zy));

	// Get sums for y calibration
	z = zx = zy = 0;
	for(j = 0; j < 5; j++) {
		z += (float)cal->yfb[j];
		zx += (float)(cal->yfb[j] * cal->x[j]);
		zy += (float)(cal->yfb[j] * cal->y[j]);
	}

	// Now multiply out to get the calibration for framebuffer y coord
	cal->a[3] = (int)((a * z + b * zx + c * zy) * (scaling));
	cal->a[4] = (int)((b * z + e * zx + f * zy) * (scaling));
	cal->a[5] = (int)((c * z + f * zx + i * zy) * (scaling));

	printf("%f %f %f\n", (a * z + b * zx + c * zy),
	       (b * z + e * zx + f * zy),
	       (c * z + f * zx + i * zy));

	// If we got here, we're OK, so assign scaling to a[6] and return
	cal->a[6] = (int)scaling;
	return 1;
	/*
	// This code was here originally to just insert default values
		for(j=0;j<7;j++) {
			c->a[j]=0;
		}
		c->a[1] = c->a[5] = c->a[6] = 1;
		return 1;
	*/

}

int main(int argc, char *argv[])
{
	calibration cal;
	int i;
	char cal_buffer[256];
	QApplication app(argc, argv);
	int cal_fd;

	tsc_dlg dlg;
	g_dlgmsg = &dlg;

	dlg.show();
	app.exec();


	printf("屏幕坐标         ADC值\r\n");
	for (int i = 0; i < 5; i++) {
		printf("(%4d,%4d)  (0x%0.4x, 0x%0.4x)\r\n",
		       screen_pt[i].x, screen_pt[i].y,
		       adc_pt[i].x, adc_pt[i].y);
	}
	printf("\r\n\r\n");


	// TODO 从  screen_pt，adc_pt  对应关系计算出 /etc/pointercal
	for(i = 0; i < 5; i++) {
		cal.x[i] = adc_pt[i].x;
		cal.y[i] = adc_pt[i].y;
		cal.xfb[i] = screen_pt[i].x;
		cal.yfb[i] = screen_pt[i].y;
	}

	if (perform_calibration (&cal)) {
		printf ("Calibration constants: ");
		for (i = 0; i < 7; i++) {
			printf("%d ", cal.a [i]);
		}
		printf("\n");

		cal_fd = open ("/etc/pointercal", O_CREAT | O_RDWR);
		sprintf (cal_buffer, "%d %d %d %d %d %d %d",
		         cal.a[1], cal.a[2], cal.a[0],
		         cal.a[4], cal.a[5], cal.a[3], cal.a[6]);
		write (cal_fd, cal_buffer, strlen (cal_buffer) + 1);
		close (cal_fd);
		i = 0;
	} else {
		printf("Calibration failed.\n");
		i = -1;
	}



	exit(4);
}




#ifdef __cplusplus
}
#endif


// #include <QProcess>
// int main()
// {
//     QProcess *process=new QProcess;
//     process->execute("iwconfig|grep IEEE|awk '{print $1}'");

//     QByteArrey iwname=process->readAllStandardOutput();
//     return 0;
// }


#include "proginfo.h"
MODULE_PROJECT(PRJ_NAME);
#if  defined(PRJ_VERSION) && defined(PRJ_PATCHLEVEL) && defined(PRJ_SUBLEVEL)
	MODULE_VERSION(PRJ_VERSION "." PRJ_PATCHLEVEL "." PRJ_SUBLEVEL);
#endif
MODULE_BUILD(__DATE__ " " __TIME__);
PROG_GITSHA1(__GIT_SHA1__);
